home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1989 / 06 / windev / ttycls.c < prev    next >
C/C++ Source or Header  |  1989-04-23  |  9KB  |  364 lines

  1. /*
  2.  * TTYCLS module
  3.  *
  4.  * Written by Bill Hall
  5.  * 3665  Benton Street, #66
  6.  * Santa Clara, CA 95051
  7.  *
  8.  * This file supports a teletype style window in either Microsoft
  9.  * windows or Presentation Manager.
  10.  *
  11.  * For an example of its use, see the source code for WINAUX
  12.  * or PMAUX.
  13.  *
  14.  * If being used in a Windows program, be sure to define WINDOWS
  15.  */
  16.  
  17. #ifdef WINDOWS
  18. #define NOCOMM        /* stops a bunch of unneeded level 3 warnings */
  19. #define NOKANJI
  20. #define NOATOMS
  21. #define NOMINMAX
  22. #include <windows.h>
  23. #else
  24. #define INCL_PM
  25. #include <os2.h>
  26. extern HAB hAB;        /* these should be defined in the main program */
  27. extern HHEAP hHeap;
  28. extern FATTRS ttyfat;
  29. #endif
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <memory.h>
  33. #include "ascii.h"
  34. #include "ttycls.h"
  35.  
  36. /* local functions */
  37. static void NEAR DoLF(PTTYWND pTTYWnd);
  38. static void NEAR DoCR(PTTYWND pTTYWnd);
  39. static void NEAR DoBS(PTTYWND pTTYWnd);
  40. static void NEAR DoTab(PTTYWND pTTYWnd);
  41.  
  42. void NEAR TTYClear(PTTYWND pTTYWnd)
  43. {
  44.     memset(pTTYWnd->pVidBuf, NUL, pTTYWnd->MaxLines * pTTYWnd->MaxLineLength);
  45.     DoCR(pTTYWnd);
  46. #ifdef WINDOWS
  47.     InvalidateRect(pTTYWnd->hWnd, (LPRECT)NULL, TRUE);
  48.     UpdateWindow(pTTYWnd->hWnd);
  49. #else
  50.     WinInvalidateRect(pTTYWnd->hWnd, (PRECTL)NULL, TRUE);
  51.     WinUpdateWindow(pTTYWnd->hWnd);    
  52. #endif
  53. }
  54.  
  55. /* 
  56.  * Called at create window time.  Creates a text buffer based
  57.  * on the passed in width, height, and the character width and height.
  58.  * Other parameters such as wrap, character mask, etc. are also set.
  59.  */
  60. InitTTYWindow(pTTYWnd,left,top,width,height,charwidth,charheight,LFonCR,CRonLF,
  61.                 wrap, fontindex, mask)
  62. PTTYWND pTTYWnd;
  63. short left, top, width, height, charwidth, charheight;
  64. BOOL LFonCR, CRonLF, wrap;
  65. unsigned short fontindex;
  66. BYTE mask; 
  67. {
  68.     
  69.     int bufsize;
  70.  
  71.     pTTYWnd->Left = left;
  72.     pTTYWnd->Top = top;
  73.     pTTYWnd->Width = width;
  74.     pTTYWnd->Height = height;
  75.     pTTYWnd->CWidth = charwidth;
  76.     pTTYWnd->CHeight = charheight;
  77.     pTTYWnd->MaxLines = height / charheight;
  78.     pTTYWnd->MaxCols = width / charwidth;
  79.     pTTYWnd->MaxLineLength = pTTYWnd->MaxCols + 1;
  80.     bufsize = pTTYWnd->MaxLines * pTTYWnd->MaxLineLength;
  81.  
  82.   /* allocate space for the display characters */
  83.   /* if allocation successful, initialize the remaining tty data */
  84.  
  85. #ifdef WINDOWS
  86.     if (pTTYWnd->hVidBuf = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, bufsize)) {
  87.     pTTYWnd->pVidBuf = LocalLock(pTTYWnd->hVidBuf); /* lock the buffer */
  88.         pTTYWnd->Pos.y = (pTTYWnd->MaxLines - 1) * charheight - 1;
  89.     pTTYWnd->hFont = (HFONT)fontindex;
  90. #else
  91.     if (pTTYWnd->pVidBuf = WinAllocMem(hHeap, bufsize)) {
  92.     memset(pTTYWnd->pVidBuf, NUL, bufsize);
  93.         pTTYWnd->Pos.y = 1;
  94.     pTTYWnd->FontIndex = fontindex;        
  95. #endif
  96.         pTTYWnd->Pos.x = 0;
  97.     pTTYWnd->oCurrentLine = pTTYWnd->CurLineOffset = 0;
  98.     pTTYWnd->oVidLastLine = (pTTYWnd->MaxLines-1) * pTTYWnd->MaxLineLength;
  99.     pTTYWnd->LFonCR = LFonCR;
  100.     pTTYWnd->CRonLF = CRonLF;
  101.         pTTYWnd->Wrap = wrap;
  102.     pTTYWnd->ebitmask = mask;
  103.       return TRUE;
  104.     }
  105.     return FALSE;
  106. }
  107.  
  108. /* display the characters contained in str */
  109. int NEAR TTYDisplay(PTTYWND pTTYWnd, short len, BYTE *str)
  110. {
  111.  
  112.     HPS hPS;
  113.     register BYTE *ptr;
  114.     register short ctr;
  115.     short toff, txpos;
  116.     BYTE *tbuf;
  117.     short cols = pTTYWnd->MaxCols;
  118.     short cwidth = pTTYWnd->CWidth;
  119.     BYTE mask = pTTYWnd->ebitmask;
  120.     
  121.     while (len) {
  122.        ptr = str;
  123.     ctr = 0;
  124.      txpos = (short)pTTYWnd->Pos.x;
  125.      tbuf = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  126.     toff = pTTYWnd->CurLineOffset;
  127.  
  128.     while((*ptr &= mask) >= SP) {
  129.         if ((len) && (toff < cols)) {
  130.         ctr += 1;
  131.         *(tbuf + toff++) = *ptr++;
  132.         txpos += cwidth;
  133.         len -= 1;
  134.         }
  135.         else
  136.         break;
  137.     }
  138.     if (ctr) {
  139. #ifdef WINDOWS
  140.         HFONT hfont = pTTYWnd->hFont;
  141.         hPS = GetDC(pTTYWnd->hWnd);
  142.         SetBkColor(hPS, GetSysColor(COLOR_WINDOW));
  143.         SetTextColor(hPS, GetSysColor(COLOR_WINDOWTEXT));
  144.         if (hfont)
  145.             SelectObject(hPS, hfont);
  146.         TextOut(hPS, pTTYWnd->Pos.x, pTTYWnd->Pos.y, (LPSTR)str, ctr);
  147.         ReleaseDC(pTTYWnd->hWnd, hPS);
  148. #else
  149.         USHORT findex = pTTYWnd->FontIndex;
  150.         hPS = WinGetPS(pTTYWnd->hWnd);
  151.         if (findex) {
  152.                 GpiCreateLogFont(hPS, (PSTR8)"TTYCLS",(LONG)findex, &ttyfat);
  153.             GpiSetCharSet(hPS,(LONG)findex);
  154.         }
  155.         GpiSetBackMix(hPS, BM_OVERPAINT);
  156.         GpiCharStringAt(hPS,(PPOINTL)&pTTYWnd->Pos,(LONG)ctr,(PCH)str);
  157.         GpiRestorePS(hPS, -1L);
  158.         WinReleasePS (hPS);
  159. #endif
  160.         if (toff < cols) {
  161.             pTTYWnd->CurLineOffset = toff;
  162. #ifdef WINDOWS
  163.             pTTYWnd->Pos.x = txpos;
  164. #else
  165.             pTTYWnd->Pos.x = (LONG)txpos;
  166. #endif
  167.         }
  168.         else
  169.         if (pTTYWnd->Wrap) {
  170.             DoCR(pTTYWnd);
  171.             DoLF(pTTYWnd);
  172.             }        
  173.     }
  174.     while ((*ptr &= mask) < SP) {
  175.         if (len) {
  176.         switch(*ptr) {
  177.             case BEL:
  178. #ifdef WINDOWS
  179.             MessageBeep(0);
  180. #else
  181.             WinAlarm(HWND_DESKTOP, WA_ERROR);
  182. #endif
  183.             break;
  184.             case HT:
  185.             DoTab(pTTYWnd);
  186.             break;            
  187.             case CR:
  188.             DoCR(pTTYWnd);
  189.             if (pTTYWnd->LFonCR)
  190.                 DoLF(pTTYWnd);
  191.             break;
  192.             case LF:
  193.             if (pTTYWnd->CRonLF)
  194.                 DoCR(pTTYWnd);
  195.             DoLF(pTTYWnd);
  196.             break;
  197.             case BS:
  198.             DoBS(pTTYWnd);
  199.             break;
  200.         }
  201.         len -= 1;
  202.         ptr++;
  203.         }
  204.         else
  205.         break;
  206.     }
  207.         str = ptr;
  208.     }
  209.     return (len);
  210. }
  211.  
  212. /* perform a carriage return */
  213. static void NEAR DoCR(PTTYWND pTTYWnd)
  214. {
  215.     pTTYWnd->CurLineOffset = 0;
  216.     pTTYWnd->Pos.x = 0;
  217. }
  218.  
  219. /* perform a line feed */
  220. static void NEAR DoLF(PTTYWND pTTYWnd)
  221. {
  222.     BYTE *pCurr;
  223.     short offset, cols;
  224.     int i;
  225.     HWND hWnd = pTTYWnd->hWnd;
  226.     cols = pTTYWnd->MaxCols;
  227.  
  228.     if ((pTTYWnd->oCurrentLine+=pTTYWnd->MaxLineLength) > pTTYWnd->oVidLastLine)
  229.     pTTYWnd->oCurrentLine = 0;
  230.     pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  231.     offset = pTTYWnd->CurLineOffset;
  232.  
  233.     for (i = 0; i < offset; i++)
  234.     *(pCurr + i) = SP;
  235.     for (i = offset; i < cols; i++)
  236.     *(pCurr + i) = NUL;
  237.  
  238. #ifdef WINDOWS
  239.     ScrollWindow(hWnd,0,-pTTYWnd->CHeight,(LPRECT)NULL,(LPRECT)NULL);
  240.     UpdateWindow(hWnd);
  241. #else
  242.     WinScrollWindow(hWnd,0,pTTYWnd->CHeight,
  243.                 NULL,NULL,NULL,NULL,SW_INVALIDATERGN);
  244.     WinUpdateWindow(hWnd);    
  245. #endif
  246. }
  247.  
  248. /* perform a backspace */
  249. static void NEAR DoBS(PTTYWND pTTYWnd)
  250. {
  251.     if (pTTYWnd->CurLineOffset > 0) {
  252. #ifdef WINDOWS
  253.     pTTYWnd->Pos.x -= pTTYWnd->CWidth;
  254. #else
  255.     pTTYWnd->Pos.x -= (LONG)pTTYWnd->CWidth;
  256. #endif
  257.     pTTYWnd->CurLineOffset -= 1;
  258.     }
  259. }
  260.  
  261. /* Horizontal tab */
  262. static void NEAR DoTab(pTTYWnd)
  263. PTTYWND pTTYWnd;
  264. {
  265.  
  266.     short curoffset, xpos, ypos, cols, cwidth;
  267.     BYTE *pCurr;
  268. #ifdef WINDOWS
  269.     RECT myrect;
  270. #else
  271.     RECTL myrect;
  272. #endif
  273.     cols = pTTYWnd->MaxCols;
  274.     curoffset = pTTYWnd->CurLineOffset;
  275.     cwidth = pTTYWnd->CWidth;
  276.  
  277.     if (curoffset < (cols - 1)) {
  278.         xpos = (short)pTTYWnd->Pos.x;        /* initialize variables */
  279.         ypos = (short)pTTYWnd->Pos.y;
  280.         pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  281.         do {
  282.         if (*(pCurr + curoffset) == NUL)  /* if null, replace with space */
  283.             *(pCurr + curoffset) = SP;
  284.         curoffset += 1;        /* update offsets */
  285.         xpos += cwidth;
  286.         } while ((curoffset % 8 != 0) && (curoffset < (cols - 1)));
  287.  
  288.     /* now invalidate the part of the screen affected */
  289. #ifdef WINDOWS
  290.     SetRect((LPRECT)&myrect, xpos, ypos, pTTYWnd->Width, pTTYWnd->Height);
  291.     InvalidateRect(pTTYWnd->hWnd, (LPRECT)&myrect, TRUE);
  292. #else
  293.     WinSetRect(hAB,&myrect,xpos,ypos,pTTYWnd->Width,ypos+pTTYWnd->CHeight);
  294.     WinInvalidateRect(pTTYWnd->hWnd, &myrect, TRUE);
  295. #endif
  296.     /* finally, reset the tty window variables */
  297.         pTTYWnd->Pos.x = xpos;
  298.         pTTYWnd->CurLineOffset = curoffset;
  299.     }
  300. }
  301.  
  302. /* repaint the window */
  303. void NEAR TTYWndPaint(PTTYWND pTTYWnd, HPS hPS, short top, short bottom)
  304. {
  305.  
  306. #ifdef WINDOWS
  307.     POINT pt;
  308.     short wtop;
  309.     HFONT hfont = pTTYWnd->hFont;
  310. #else
  311.     USHORT findex = pTTYWnd->FontIndex;
  312.     POINTL pt;
  313. #endif
  314.     BYTE *lineptr;
  315.     BYTE *pBuf, *pEnd;
  316.     short lines, length;
  317.     short cheight;
  318.     int i;
  319.  
  320.     pt.x = 0;
  321.     pBuf = pTTYWnd->pVidBuf;
  322.     pEnd = pBuf + pTTYWnd->oVidLastLine;
  323.  
  324.     lineptr = pBuf + pTTYWnd->oCurrentLine;
  325.     pt.y = pTTYWnd->Pos.y;
  326.  
  327.     length = pTTYWnd->MaxLineLength;
  328.     cheight = pTTYWnd->CHeight;
  329. #ifdef WINDOWS
  330.     wtop = pTTYWnd->Height - top;
  331.     lines = wtop / cheight;
  332.     if (wtop % cheight)
  333.     lines += 1;
  334.     lines = min(pTTYWnd->MaxLines, lines);
  335.     SetBkColor(hPS, GetSysColor(COLOR_WINDOW));
  336.     SetTextColor(hPS, GetSysColor(COLOR_WINDOWTEXT));
  337.     if (hfont)
  338.         SelectObject(hPS, hfont);
  339. #else
  340.     lines = top / cheight;
  341.     if (top % cheight)
  342.     lines += 1;
  343.     lines = min(pTTYWnd->MaxLines, lines);
  344.     GpiErase (hPS);
  345.     GpiSetBackMix(hPS, BM_OVERPAINT);
  346.     if (findex) {
  347.         GpiCreateLogFont(hPS, (PSTR8)"TTYCLS",(LONG)findex, &ttyfat);
  348.         GpiSetCharSet(hPS,(LONG)findex);
  349.     }
  350. #endif
  351.  
  352.     for (i = 0; i < lines; i++) {
  353. #ifdef WINDOWS
  354.         TextOut(hPS, pt.x, pt.y, (LPSTR)lineptr, strlen(lineptr));
  355.     pt.y -= cheight;
  356. #else
  357.         GpiCharStringAt(hPS,&pt,(LONG)strlen(lineptr),(PCH)lineptr);
  358.     pt.y += (LONG)cheight;
  359. #endif
  360.         if ((lineptr -= length) < pBuf)
  361.         lineptr = pEnd;
  362.     }
  363. }
  364.